블로그스팟(Blogger)은 무료이면서도 강력한 블로그 플랫폼이지만, 기본 기능만으로는 “관련 글 자동 연결”이 제공되지 않습니다. 이 글에서는 구글 SEO를 고려한 내부 링크 자동 생성 방법을 소개합니다.

블로그스팟 관련 글 내부 링크 자동 생성 방법

왜 관련 글 자동 생성이 중요한가요?

  • 내부 링크 강화로 SEO 최적화
  • 방문자 이탈률 감소 → 블로그 체류 시간 증가
  • 콘텐츠 탐색 흐름 유도로 사용자 경험 향상

적용 방법 요약

<data:post.body/> 바로 아래에 관련 글 HTML 코드 삽입
<div class='related-posts' role='navigation'>
    <h2>관련 글</h2>
    <script id='related-posts-site-json' type='application/json'>
        {
            &quot;debug&quot;: false,
            &quot;homepageUrl&quot;: &quot;<data:blog.homepageUrl/>&quot;,
            &quot;params&quot;: &quot;orderby=updated&quot;,
            &quot;url&quot;: &quot;<data:post.url/>&quot;,
            &quot;title&quot;: &quot;<data:post.title.jsonEscaped/>&quot;,
            &quot;snippet&quot;: &quot;<data:post.snippets.short.jsonEscaped/>&quot;,
            &quot;useSnippet&quot;: true,
            &quot;useLastPosts&quot;: true,
            &quot;min&quot;: -1,
            &quot;max&quot;: 5,
            &quot;prefix&quot;: &quot;<ul class='related-post'>&quot;,
            &quot;sufix&quot;: &quot;</ul>&quot;,
            &quot;dummy&quot;: &quot;<li>&amp;nbsp;</li>&quot;,
            &quot;format&quot;: &quot;<li><a href='${url}'>${title}</a></li>&quot;,
            &quot;labels&quot;: [<b:loop index='i' values='data:post.labels' var='label'><b:if cond='data:i != 0'>,</b:if>&quot;<data:label.name.jsonEscaped/>&quot;</b:loop>]
        }
    </script>
	</div>

</style> 위에 관련 글 디자인 CSS 추가
.related-posts h2 {
  font-size: 1.4em;
  margin-bottom: 20px;
  font-weight: bold;
  color: #333;
  border-bottom: 2px solid #ff6b6b;
  padding-bottom: 8px;
}

/* 번호 있는 리스트 스타일 */
.related-posts ul.related-post {
  counter-reset: related-counter;
  list-style: none;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.related-posts ul.related-post li {
  counter-increment: related-counter;
  background-color: #fff;
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 12px 16px 12px 48px; /* 왼쪽 여백 추가 */
  position: relative;
  transition: 0.2s ease-in-out;
  font-size: 1em;
}

.related-posts ul.related-post li::before {
  content: counter(related-counter) &quot;.&quot;;
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-weight: bold;
  color: #ff6b6b;
  font-size: 1.1em;
}

.related-posts ul.related-post li:hover {
  background-color: #ffefef;
  border-color: #ff6b6b;
  transform: translateY(-2px);
}

.related-posts ul.related-post li a {
  text-decoration: none;
  color: #333;
  font-weight: 500;
}

.related-posts ul.related-post li a:hover {
  color: #e60000;
}
</body> 위에 FeedRelatedPosts.js 스크립트 삽입
<script>
//<![CDATA[
/*! FeedRelatedPosts.js v2.2 | MIT License | https://github.com/k08045kk/FeedRelatedPosts.js/blob/master/LICENSE */ !function(e,t){if(!e.FeedRelatedPosts){let a=e.FeedRelatedPosts||function(){},l=a.pages=a.pages||[],s=a.labels=a.labels||[];for(let r=0;r<2;r++){let n=0==r?a.siteJsonQuery||"#related-posts-site-json":a.pageJsonQuery||"#related-posts-page-json",i=document.querySelector(n);try{let p=i&&JSON.parse(i.textContent)||{};for(let o in Array.prototype.push.apply(l,p.pages||[]),Array.prototype.push.apply(s,p.labels||[]),p)p.hasOwnProperty(o)&&(a[o]=p[o])}catch(u){}}a.pages=!0===a.pushPages?l:a.pages,a.labels=!0===a.pushLabels?s:a.labels,e.FeedRelatedPosts=t(a,document),!1!==a.run&&e.FeedRelatedPosts.init()}}(this,function(e,t){"use strict";let a=function(e){let a=t.createElement("script");a.type="text/javascript",a.async=!0,a.src=e;let l=t.getElementsByTagName("script")[0];l.parentNode.insertBefore(a,l)},l=function(){let e=/&#(\d+);|&\w+;/g,t={"&nbsp;":" ","&lt;":"<","&gt;":">","&amp;":"&","&quot;":'"',"&apos;":"'"};return function(a){return a.replace(e,function(e,a){return"#"==e.charAt(1)?String.fromCharCode(a-0):t.hasOwnProperty(e)?t[e]:e})}}(),s=function(e,t){t=t||new Set;let a=/[A-Z]+[a-z]*|[A-Z]*[a-z]+|'[A-Z]*[a-z]*|[0-9]+|[^A-Za-z0-9'"!\?\-:;,\.\s]+/g,l;for(;null!==(l=a.exec(e));)254>=l[0].charCodeAt(0)?t.add(l[0].toLowerCase()):r(l[0],t);return t},r=function(e,t){e="  "+e.toLowerCase()+"  ",t=t||new Set;for(let a=e.length-2;a--;)t.add(e.substring(a,a+3));return t},n=function(e,t){let a=0;return t.forEach(function(t){e.has(t)&&(a+=1)}),a/(e.size+t.size-a)},i=function(e){let a=[];e.pageMap.forEach(function(e){e.score>=0&&a.push(e)}),a.sort(function(e,t){return t.score-e.score||new Date(t.updated)-new Date(e.updated)});let l=Math.min(e.max,a.length);if(e.min<=l){let s=[],r=0;for(;r<l;r++)s.push(e.format.replace(/\${(.*?)}/ig,function(e,t){let l="";return l="$"===t.toLowerCase()?"$":a[r].hasOwnProperty(t)?a[r][t]:""}));if(-1==e.min)for(;r<e.max;r++)s.push(e.dummy||"");let n=(e.prefix||"")+s.join("")+(e.sufix||""),i=e.insertQuery||"#related-posts-site-json",p=e.insertAdjacent||"afterend";t.querySelector(i).insertAdjacentHTML(p,n)}!0!==e.debug&&(e.pageMap=null),e.state="complate"};return e.add=function(t){let a=e;if("loading"==a.state){try{for(let l=0;l<t.feed.entry.length;l++){let s=t.feed.entry[l];for(let r=0;r<s.link.length;r++)if("alternate"==s.link[r].rel){if(!a.pageMap.has(s.link[r].href)){let p=a.gramify(s.link[r].title);!0===a.useSummary&&s.summary&&s.summary.$t&&a.gramify(s.summary.$t,p);let o=n(a.set,p);!0!==a.onlyThumbnail||s.media$thumbnail&&s.media$thumbnail.url||(o=-1),a.pageMap.set(s.link[r].href.split("?")[0],{url:s.link[r].href,title:s.link[r].title,updated:s.updated?s.updated.$t:"",thumbnail:s.media$thumbnail?s.media$thumbnail.url:"",score:o})}break}}}catch(u){}a.count=a.count+1,a.count>=a.limit&&i(a)}},e.init=function(){var n=e;if(!n.state){if(n.state="init",n.url=n.url||location.href,n.title=n.title||t.title,n.labels=n.labels||[],n.url=n.url.split(/\?|#/)[0],n.count=0,n.limit=n.labels.length+(!0===n.useLastPosts?1:0),n.pageMap=new Map,n.pageMap.set(n.url,{score:-1}),null==n.min&&(n.min=1),null==n.max&&(n.max=5),!n.homepageUrl){let p=n.url.match(/^(.+?):\/\/(.+?):?(\d+)?(\/.*)?$/);n.homepageUrl=p[1]+"://"+p[2]+(p[3]?":"+p[3]:"")+"/"}n.homepageUrl=n.homepageUrl.split("?")[0],n.gramify="engramify"==n.useSetType?s:r,n.set=n.gramify(n.title),!0===n.useSnippet&&n.snippet&&(n.snippet=l(n.snippet),n.gramify(n.snippet,n.set));for(let o=0;o<n.pages.length;o++)!1!==n.pages[o].visible&&(n.pages[o].score=n.pages.length+1-o,n.pageMap.set(n.pages[o].url,n.pages[o]));if(n.pageMap.size<n.max){if(n.excludedAnkersQuery){let u=t.querySelectorAll(n.excludedAnkersQuery);for(let f=0;f<u.length;f++)n.pageMap.set(u[f].href,{score:-1})}let m=n.homepageUrl+"feeds/posts/summary",c="?alt=json&callback=FeedRelatedPosts.add"+(n.params?"&"+n.params:""),g=/(^|&)max-results=/.test(n.params);if(0==n.limit)n.min<=n.pageMap.size&&i(n);else if(1==n.labels.length)a(m+"/-/"+n.labels[0]+c+(g?"":"&max-results=100"));else if(2==n.labels.length)a(m+"/-/"+n.labels[0]+c+(g?"":"&max-results=50")),a(m+"/-/"+n.labels[1]+c+(g?"":"&max-results=50"));else for(let d=0;d<n.labels.length;d++)a(m+"/-/"+n.labels[d]+c);!0===n.useLastPosts&&a(m+c)}else i(n);n.state="loading"}},e});
//]]>
</script> 

라벨 기반 추천 알고리즘

관련 글은 현재 포스트의 라벨(Label)을 기준으로 최대 5개까지 자동 표시됩니다. 라벨이 동일한 최신 글이 우선 추천되므로, 라벨 정리는 필수입니다.

SEO 최적화 효과

  • 검색봇이 내부 페이지를 더 깊이 탐색
  • 다양한 키워드 간 자연스러운 연결 구축
  • 사용자의 클릭을 유도해 페이지 체류 시간 증가

적용 시 주의사항

  • 페이지가 깨질 경우 스크립트 / 스타일 / HTML 각각 제거하며 점검
  • 포스트마다 반드시 라벨이 1개 이상 포함되어야 정상 작동
  • 썸네일이 없는 경우에도 오류 없이 출력됨